<?php
/**
 * @author Adam Zivner <adam.zivner@gmail.com>
 * @license http://www.opensource.org/licenses/bsd-license.php New BSD license
 * @package AttoMVC https://code.google.com/p/attomvc/
 */

class AttoController {
	/** @var AttoView */
	protected $view;

	/** @var AttoArray - Request (GET, POST) arguments processed according to accompanied informations. */
	protected $request;

	protected $controller_name = null;
	protected $action_name = null;

	public function __construct()
	{
		$this->view = new AttoView();

		// Controller classes are by convention named SomethingController
		$name = strtolower(get_class($this));
		$name = substr($name, 0, -10); // cut out "controller" at the end

		$this->controller_name = $this->view->controller_name = $name;

		$this->init();
	}

	/** Used by controllers for initialization instead of __construct() */
	public function init() {}

	/**
	 * Dispatch controller action.
	 *
	 * @param string $action
	 * @param AttoArray $request - complete unprocessed request
	 */

	public function dispatch($action, $request)
	{
		$this->request = $request;

		if(strlen($action) == 0) // default action
			$action = "index";

		$this->action_name = $this->view->action_name = $action;

		$action_method = $action . "Action";
		$this->view->script_path = $this->controller_name . "/" . $this->action_name . ".phtml";

		if(!method_exists($this, $action_method))
			throw new Exception("Specified action '$action' does not exist.");

		if(!isset($this->$action))
			$this->$action = array();

		$this->preDispatch($action);

		$data = array(); // It will sent to the action

		$classRef = new ReflectionObject($this);
		$methodRef = new ReflectionMethod($classRef->getName(), $action_method);

		foreach($methodRef->getParameters() as $param) {
			$name = $param->getName();

			if(isset($request[$name]))
				$data[$name] = $request[$name];
			else if($param->isOptional()) // If there is default value, use it
				$data[$name] = $param->getDefaultValue();
			else
				throw new Exception("Parameter '$name' cannot be empty");
		}

		call_user_func_array(array($this, $action_method), $data);

		$this->postDispatch($action);

		echo $this->view->render();
	}

	/** Executed before action method of the controller is called */
	public function preDispatch() {}
	/** Executed after action method of the controller is called */
	public function postDispatch() {}
}